home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-13 / dte5_1.zip / DTE.DOC < prev    next >
Text File  |  1991-02-06  |  22KB  |  399 lines

  1. BACKGROUND
  2. ==========
  3.  
  4. "dte" is a simple full-screen text editor suitable for editing program
  5. source code. It was designed with the following goals:
  6.     1. To perform well over slow serial communication lines;
  7.     2. To imitate the command keys used in WordStar / Turbo Pascal;
  8.     3. To be readily portable to different hardware.
  9.  
  10. Slow serial communication lines pose some unique problems for full-
  11. screen text editors. On a 1200 baud line, a 24 line by 80 column
  12. screen can take up to 16 seconds to transmit (although with normal
  13. program text 8 seconds would be more typical, since most lines will
  14. not be the full 80 columns). Most text editors simply input a command,
  15. update the screen to show the effect of the command, then input
  16. another command and so on. Usually this is acceptable. However,
  17. consider the case where the user types the command to move a page down
  18. in the file, then immediately changes his mind and types the command
  19. to move back up a page. Between when the user entered the first
  20. command and when he entered the second command, the computer might
  21. have updated one or two lines on the screen. After the second command
  22. was entered, the computer should only have had to undo these few
  23. changed lines. However, with many text editors, the computer would
  24. completely finish updating the screen before the second command was
  25. even registered, and then have to completely redraw the screen to make
  26. it the way it used to be - a total of about 16 wasted seconds for the
  27. poor user! "dte" notices commands as soon as they are typed, and
  28. always updates the screen to match the desired final state.
  29.  
  30. If the user is to be able to take full advantage of this ability to
  31. enter new commands before the screen is completely updated from
  32. earlier ones, then it would be helpful if the lines closest to the
  33. cursor could be updated before the rest of the screen; this would give
  34. the user a context in which to decide what to do next. "dte" always
  35. updates the cursor line first, and then alternately updates lines
  36. above and below the cursor until the screen is complete.
  37.  
  38. There has been much debate over whether modeless editors are
  39. intrinsically easier to use than editors with all sorts of modes. My
  40. personal view is that modes are acceptable in two situations:
  41.     1. The mode can be left set for an entire editing session;
  42.     2. The mode only lasts for the next keystroke, then reverts to
  43.        normal automatically.
  44. I believe the problems usually arise when modes last for some time,
  45. but must be changed periodically during a normal editing session. The
  46. problem is increased if the difference between what the same
  47. keystrokes achieve is drastically different between different modes.
  48.  
  49. "dte" has several modes in the first class. Insert mode determines
  50. whether normal printable characters typed will be inserted in front of
  51. the cursor, or whether they will overwrite the character under the
  52. cursor. Insert mode will usually be left on all the time, and if the
  53. user forgets which mode he is using, the worst effect will be the loss
  54. of a few characters that get overwritten by characters that were
  55. intended to be inserted. Indent mode determines whether, when the user
  56. types the carriage return key, the new line inserted will begin in
  57. column 0, or will be indented to match the line above. Indent mode
  58. will usually be left on for program editing, and if the user forgets
  59. which mode is in effect all that will be needed to correct the problem
  60. is to insert or delete a few spaces. Finally, unindent mode determines
  61. whether, when the cursor is on the first non-blank character of a line
  62. and the user types backspace, just one character should be deleted, or
  63. whether enough characters should be deleted to match the indentation
  64. of an earlier line. Unindent mode will normally be on for program
  65. editing, and if the user forgets which mode is in effect, the only
  66. problem will be a few too many or too few spaces deleted.
  67.  
  68. "dte" also has several modes in the second class. Since "dte" has over
  69. 50 different commands, it was not possible to use a different control
  70. key for each command. Therefore, some control keys have been reserved
  71. as "escape" keys, to create two-key commands. In these cases, the mode
  72. is indicated by a small marker in the top left corner of the screen,
  73. and the mode only lasts until the next single key has been pressed.
  74.  
  75. "dte" does have a few commands that do not fit either class. For
  76. example, the command to find the next occurrence of a particular
  77. string requires the user to enter the search string. In these cases,
  78. the user is prompted for whatever needs to be entered. These
  79. exceptions seem inevitable - after all, if normal characters were
  80. always inserted at the cursor, it would not (readily) be possible to
  81. search for a string containing normal characters!
  82.  
  83. Since "dte" was to be a relatively modeless editor, and yet at the
  84. same time was to work with typical so-called "intelligent" terminals,
  85. it was assumed that only printable ASCII characters and control codes
  86. could be returned by the terminal. Thus all of the "dte" commands had
  87. to be constructed from the control codes. My personal view is that
  88. MicroPro did an excellent job of this mapping with WordStar, and
  89. evidently Borland agree since the default commands for Turbo Pascal
  90. are also WordStar compatible where appropriate. Even if I had not
  91. liked this set of commands, I would still have been almost forced to
  92. use it, since most of my potential users were already familiar with
  93. Turbo Pascal.
  94.  
  95. This is the other major advantage of "dte" over the existing full-
  96. screen text editors on our UNIX minicomputer: it uses a set of
  97. commands that are already familiar to most of the staff and students
  98. from using microcomputers. For a student who normally uses Turbo
  99. Pascal on a microcomputer, and only logs in to the minicomputer to
  100. send electronic mail, it is very frustrating to have to learn a
  101. complete new set of editor commands! Many simply ignore the electronic
  102. mail facility, which makes life difficult for staff who have to try to
  103. debug programs by telephone instead!!
  104.  
  105. One of my more interesting design decisions was what to do about
  106. moving the cursor beyond the last character in a line. WordStar does
  107. not allow this (the cursor simply cannot be moved anywhere unless
  108. there is actually a character there in the text). On the other hand,
  109. Turbo Pascal permits the cursor to be placed anywhere. Since "dte" was
  110. to be a program editor, I chose the Turbo Pascal approach. However, I
  111. then had the problem of what to do about trailing white space at the
  112. end of a line. All the user has to do is type a character when the
  113. cursor is beyond the end of a line, and then delete the character
  114. again, and there will be a number of spaces hanging at the end of the
  115. line wasting memory. If this trailing space is removed as soon as the
  116. cursor leaves the line (the Turbo Pascal approach), then there is a
  117. problem: if the cursor is beyond the end of the line, and the user
  118. types the carriage return key, then changes his mind and types the
  119. backspace key, the cursor finishes up at the end of the visible text
  120. of the line, not where it started from. To avoid this, I have left the
  121. trailing space there, but removed it when starting to edit a line (by
  122. which time the cursor is already positioned). Trailing space is also
  123. removed as the file is being saved to disk. Thus, although it is
  124. possible to get some wasted memory in trailing space, the problem is
  125. not likely to accumulate over time!
  126.  
  127. Initially, "dte" did not worry about file attributes (read/write/
  128. execute) at all: if a file was read only, then after editing it had to
  129. be saved to a different name, and every file saved was simply given
  130. the default attributes. However, this caused problems with editing
  131. shell scripts, since every time a file was saved it lost its "execute"
  132. attribute! Now "dte" notes the attributes of a file when it starts
  133. editing, changes these attributes temporarily so the owner can write
  134. the file to save an edited version (if the file was read only), and
  135. finally changes the attributes back to what they were originally. The
  136. assumption is that if the user explicitly asks to edit a given file,
  137. then the editor should automatically perform any necessary "chmod"
  138. operations, rather than forcing the user to do this manually. (The
  139. user is asked to confirm before a read only file is overwritten.) This
  140. is very convenient for editing AUTOEXEC.BAT if it is a hidden read-
  141. only file. An interesting side effect of this under the Novell LAN is
  142. that a shareable/read-only file can be edited and remain
  143. shareable/read-only!
  144.  
  145. Although the features of this editor have generally been kept to the
  146. absolute workable minimum, I could not resist the temptation of
  147. implementing multiple windows. Turbo Pascal does not quite support
  148. this, although it comes half way by remembering the cursor position
  149. and marked blocks in files that have been edited in the current
  150. session. WordStar (5.0) does support multiple windows, but only two.
  151. WordStar also has the problem (I think it is a problem, anyway - the
  152. manual suggests some possible benefits!) that if the same file is
  153. loaded into both windows, and both windows are edited, then changes
  154. made in one window do not appear in the other window, and the window
  155. that is saved last will overwrite the first one! "dte" supports
  156. multiple windows (only limited by the number of lines available on the
  157. screen), and if two windows are opened with the same file name, then
  158. the windows actually reference the same file text. This means that if
  159. two windows contain the same section of the same file, then any
  160. changes made in one window will simultaneously appear in the other
  161. window. If for some reason it is actually desirable to open a window
  162. on the original version of a file (for example, to restore something
  163. that has accidentally been deleted), the same file can be accessed
  164. with a different name (for example, "fred" in one window, and "./fred"
  165. in the other). "dte" is not clever about recognizing alternative
  166. paths!
  167.  
  168. I chose this design because I often find it convenient to view (say)
  169. type declarations at the start of a file, and code accessing variables
  170. of the various types in the middle of the file. It is nice to be able
  171. to see both at once without having to get a printout, and it is even
  172. nicer if both the code and the types can be changed at the same time.
  173.  
  174. Since Turbo Pascal has no window commands, I restricted myself to the
  175. two WordStar window commands: open/change window, and resize window.
  176. In WordStar, if there is only one window, the open/change command
  177. opens a new window, and if there are two windows, it moves the cursor
  178. to the other window. In "dte", there may be multiple windows, so the
  179. open/change command has to ask the user which window to change to, or
  180. whether the user would like a new window. Windows are numbered
  181. relatively from the current window, so selecting "-1" (or just "-")
  182. moves to the previous window, and selecting "1" moves to the next
  183. window down. Selecting "new" (the default) will cause the user to be
  184. prompted for a new file name (for which the default is the same file
  185. as the current window). In WordStar, the new window automatically
  186. takes up half the screen. In "dte", the cursor line becomes the bottom
  187. line of the current window, and the new window starts from the line
  188. below the cursor, and continues down to what used to be the bottom of
  189. the current window. The resize command is similar: the cursor line
  190. becomes the bottom line of the current window (or the top line if the
  191. current window is at the bottom of the screen).
  192.  
  193. WordStar provides commands for copying and moving blocks between
  194. windows. Since in "dte" it would be necessary to specify which window,
  195. I decided these commands would be more trouble to use than they were
  196. worth. It is always possible to write a block to a file, change
  197. windows, and then read the block back in again.
  198.  
  199. Originally, "dte" refused to edit files containing control or other
  200. unprintable characters. However, this caused problems with some mainly
  201. text files (which sometimes needed to contain form feed characters),
  202. and also made reading files rather slow. Therefore, "dte" now copes
  203. with control characters, by displaying (say) control-A as a capital A
  204. with highlighting to distinguish it from a normal A.
  205.  
  206.  
  207. MAJOR DATA STRUCTURES
  208. ===== ==== ==========
  209.  
  210. The main data structure used by "dte" is an enormous character array
  211. that stores all the files being edited. However, inserting individual
  212. characters by moving the entire remainder of the file (and any
  213. subsequent files) was too slow, so the current line is copied into a
  214. special buffer for editing, and the buffer is inserted into the main
  215. text when the cursor is moved off the line. This causes numerous
  216. complications, since position markers (for example, marking the
  217. beginning and end of a block) may be set within the line buffer, and
  218. there may be no corresponding position in the main text buffer until
  219. the text from the line buffer gets inserted.
  220.  
  221. Another significant data structure is a copy of the current terminal
  222. screen, complete with characters and attributes. Whenever the screen
  223. needs to be updated, this copy is compared with what should be there,
  224. so that only the parts of the screen that have actually changed need
  225. to be transmitted to the terminal. I was originally going to use the
  226. curses package, but I gave up on this when curses failed to take
  227. advantage of a delete line command and instead redrew the entire
  228. screen after the top line had been deleted!!! Since I had to choose
  229. some data structure to represent characters and attributes, I chose
  230. the one actually used by the screen memory of the IBM PC. This means
  231. that it is possible to actually use the video display RAM directly
  232. rather than having a separate copy - see "hwibm.c" for more details.
  233.  
  234. In addition to the screen image, there is quite a bit of other
  235. information which is global to an editing session. This includes
  236. things like the current insert, indent and unindent modes, and the
  237. current tab interval. Rather than use global variables for each of
  238. these on the one hand, or pass countless parameters on the other,
  239. "dte" defines a special structure (status_infos) with fields for each
  240. of these parameters. See the structure definition in "common.h" for
  241. details.
  242.  
  243. The other major data structures are for windows and files. For every
  244. window, we need to know where the cursor is (both on the screen and in
  245. the text), which file is displayed in the window, which screen lines
  246. are allocated to the window and so on. For each file, we need to know
  247. the file name, the positions of any markers set in the text, the start
  248. and end of the file text in the text buffer and so on. This
  249. information needs to be kept separate from the window data, since it
  250. is quite possible to have two windows open in the same file.
  251.  
  252. It is perhaps worth noting here my use of the "text_ptr" type. On most
  253. UNIX systems, this will simply be defined (in "common.h") as a normal
  254. character pointer. However, on the PC and possibly other computers
  255. with segmented architectures, normal character pointers are restricted
  256. to 64K objects. This was not sufficient for "dte", since I wanted to
  257. be able to cope with files as large as could be fitted in memory.
  258. Fortunately Turbo C provides a qualifier called "huge", which allows a
  259. pointer to work with objects larger than 64K. Since this is not
  260. standard, I have used the "text_ptr" type everywhere that I might need
  261. to increment a pointer over a 64K boundary. (For other segmented
  262. machines, it might be important to note that Turbo C normalizes huge
  263. pointers so that the segment contains 16 bits of the address, and the
  264. offset contains only 4 bits. This means that a huge pointer can be
  265. assigned to a normal pointer, and the normal pointer can then be
  266. incremented at least 64K - 16 bytes before any problems occur. I have
  267. taken advantage of this to use normal pointers when I know I will only
  268. be looking at a small section of the text buffer.)
  269.  
  270.  
  271. ALGORITHMS
  272. ==========
  273.  
  274. Knowing the commands that must be supported (see dte.hlp) and the
  275. major data structures used, the algorithms generally follow
  276. automatically. The main loop of this program repeatedly calls the
  277. "update display to match what it should look like" routine. This
  278. routine updates the display, and then waits for a command, then
  279. executes the command, and then returns. However, if a command is
  280. entered while the display is being updated, the update is aborted and
  281. the command executed immediately. Next time the display routine is
  282. called, it can complete the previous update if this is still
  283. appropriate.
  284.  
  285. The following source files have been used:
  286.     ed.c      - the main editor module, and a number of the smaller
  287.                 miscellaneous editing commands which did not seem to
  288.                 belong in any of the other files
  289.               - code for dispatching commands
  290.                                 1
  291.     block.c   - all the commands that manipulate blocks (block move,
  292.                 copy, read, write etc)
  293.               - code for setting position markers
  294.     findrep.c - the functions relating to finding text and replacing
  295.                 text
  296.               - the code for moving the cursor to various other
  297.                 positions in the file (such as the start of the marked
  298.                 block)
  299.     window.c  - the code associated with opening and sizing windows,
  300.                 and also displaying the help window
  301.     utils.c   - miscellaneous functions that were required in more
  302.                 than one of the other files, or were thought to be
  303.                 likely to be used elsewhere in the future
  304.               - the code for updating the display to match what it
  305.                 should look like
  306.     hwind.c   - the code to interface the rest of the editor to the
  307.                 display and input hardware
  308.     hwXYZ.c   - all the code that needs to be different on different
  309.                 hardware (for example, "hwhpux.c" for HP-UX, "hwibm.c"
  310.                 for IBM PC and so on)
  311.  
  312. See the source code for full details.
  313.  
  314.  
  315. LIMITATIONS
  316. ===========
  317.  
  318. "dte" will only edit a file that will fit into memory. It is up to the
  319. individual implementor to decide what is a reasonable limit, or to
  320. work out how much memory is actually available.
  321.  
  322. "dte" does not do a good job of handling lines greater than 80
  323. characters wide. Such lines are permitted (up to a certain limit), but
  324. only the first 80 characters can be seen on the terminal. No attempt
  325. is made at horizontal scrolling or wrapping of long lines. It is my
  326. belief that program source code should not contain lines longer than
  327. 80 characters anyway...
  328.  
  329. "dte" will not let the user enter control characters into the files it
  330. is editing (with the exception of tab characters, which are expanded
  331. into the required number of spaces). Support for anything other than
  332. plain ASCII text files is very limited.
  333.  
  334. "dte" does not handle tab characters in the files it edits. If a file
  335. contains tab characters, these will usually be displayed just like any
  336. other control characters, unless the user requests a file to be read
  337. with tab expansion. Once tabs have been expanded, only spaces will be
  338. present in the output file.
  339.  
  340. "dte" distinguishes control characters by using video attributes. On
  341. terminals without video attributes, control characters will not be
  342. distinguishable from ordinary characters!
  343.  
  344. "dte" does not attempt to use highlighting on "magic cookie"
  345. terminals. This makes it hard to remember exactly where a marked block
  346. is. If anyone can think of a really good way of doing highlighting on
  347. these terminals, please give me your suggestions!
  348.  
  349. "dte" is reasonably efficient in the number of characters that it
  350. transmits to a terminal, but not very efficient of CPU time in working
  351. out what needs to be transmitted. This becomes obvious in the PC
  352. version, where on a standard 4.77 MHz PC "dte" only manages the
  353. equivalent of about 4800 baud!
  354.  
  355. "dte" is a text editor, NOT a word processor.
  356.  
  357.  
  358. LICENSING
  359. =========
  360.  
  361. It is not my intention to restrict the use of this source code in any
  362. way. However, common courtesy dictates that my original authorship
  363. should be acknowledged, and if you are providing modified source code
  364. I would appreciate it if you could make clear which parts of the code
  365. were modified by you.
  366.  
  367. I have often felt frustrated that I cannot use even small sections of
  368. an existing program due to copyright restrictions, and instead have to
  369. reinvent the wheel. It is for this reason that I release this source
  370. code into the public domain.
  371.  
  372.  
  373. ORIGIN
  374. ======
  375.  
  376. This entire editor was written by Douglas Thomson, a computing
  377. lecturer at Monash University College Gippsland. Any ideas for
  378. improvements should ideally be reported by e-mail to:
  379.     doug@giaea.oz
  380. Alternatively, mail to:
  381.     Douglas Thomson
  382.     c/- Computing
  383.     M.U.C.G.
  384.     Switchback Road
  385.     Churchill
  386.     Victoria   3842
  387.     AUSTRALIA
  388.  
  389. Even if you have no suggestions for improvements, I would still like
  390. to hear from anyone who actually makes any use of this code. If I hear
  391. nothing, I will conclude that I am wasting my time posting this sort
  392. of thing!
  393.  
  394. Note: Although I will try to solve any problems found with this
  395.       editor, I cannot guarantee how long it will be before I have
  396.       time to even look at a given problem! Since I have provided the
  397.       source code, there are many other programmers just as capable of
  398.       fixing any problems as I.
  399.